﻿/// Copyright © 2013 Microsoft Corporation. 
/// This project is released under the Microsoft Public License (MS-PL)
///
namespace DataMorph.Generator
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;

    using DataMorph.Common.Contracts;

    public class TagDataFileGenerator : ITagDataFileGenerator
    {
        private static readonly ThreadLocal<Random> Random = new ThreadLocal<Random>(() => new Random());

        private readonly ITagDataGenerator tagDataGenerator;

        public TagDataFileGenerator(ITagDataGenerator tagDataGenerator)
        {
            this.tagDataGenerator = tagDataGenerator;
        }

        public TagDataFile Generate(IEnumerable<Tag> tags, int sizeInBytes, DateTime startDateTime, DateTime endDateTime)
        {
            if (tags == null)
            {
                throw new ArgumentNullException("tags", "Tag collection must not be null.");
            }

            if (!tags.Any())
            {
                throw new ArgumentException("Tag collection must not be empty.", "tags");
            }

            if (sizeInBytes <= 0)
            {
                throw new ArgumentException("Size of file must be greater than 0.");
            }

            if (startDateTime >= endDateTime)
            {
                throw new ArgumentException("Start time must not be greater or equal to end time.");
            }

            var file = new TagDataFile();
            var tagList = tags as IList<Tag> ?? tags.ToList();
            var fileSize = 0;

            do
            {
                var tag = tagList[Random.Value.Next(0, tagList.Count)];
                var tagData = this.tagDataGenerator.Generate(tag);

                fileSize += tagData.Length;

                file.Lines.Add(tagData);
            } 
            while (fileSize <= sizeInBytes);

            file.Lines.RemoveAt(file.Lines.Count - 1);

            var startTicks = startDateTime.Ticks;
            var ticks = (endDateTime - startDateTime).Ticks / file.Lines.Count;
            for (int i = 0; i < file.Lines.Count; i++)
            {
                file.Lines[i].Ticks = startTicks + (i * ticks);
            }

            return file;
        }
    }
}